home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / phillip2 / edge2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-11  |  13.5 KB  |  533 lines

  1.  
  2.     /***********************************************
  3.     *
  4.     *    file d:\cips\edge2.c
  5.     *
  6.     *    Functions: This file contains
  7.     *       homogeneity
  8.     *       difference_edge
  9.     *       contrast_edge
  10.     *       range
  11.     *       variance
  12.     *
  13.     *    Purpose:
  14.     *       These functions implement several
  15.     *       types of advanced edge detection.
  16.     *
  17.     *    External Calls:
  18.     *       wtiff.c - round_off_image_size
  19.     *                 create_file_if_needed
  20.     *                 write_array_into_tiff_image
  21.     *       tiff.c - read_tiff_header
  22.     *       rtiff.c - read_tiff_image
  23.     *       numcvrt.c - get_integer
  24.     *       edge.c - fix_edges
  25.     *
  26.     *    Modifications:
  27.     *       26 March 1991 - created
  28.     *       30 December 1992 - added the range and
  29.     *           variance edge detectors.
  30.     *
  31.     *************************************************/
  32.  
  33. #include "cips.h"
  34.  
  35.  
  36. short e_mask[3][3] = {
  37.        {-9,  0, -9},
  38.        { 0, 36,  0},
  39.        {-9,  0, -9} };
  40.  
  41. short contrast[3][3] = {
  42.    {  1,  1,  1},
  43.    {  1,  1,  1},
  44.    {  1,  1,  1}};
  45.  
  46.  
  47.    /**************************************************
  48.    *
  49.    *   homogeneity(...
  50.    *
  51.    *   This function performs edge detection by looking
  52.    *   for the absence of an edge.  The center of a
  53.    *   3x3 area is replaced by the absolute value of
  54.    *   the max difference between the center point
  55.    *   and its 8 neighbors.
  56.    *
  57.    ***************************************************/
  58.  
  59.  
  60. homogeneity(in_name, out_name, the_image, out_image,
  61.              il, ie, ll, le, threshold, high)
  62.    char   in_name[], out_name[];
  63.    int    high, il, ie, ll, le, threshold;
  64.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  65. {
  66.    int a, b, absdiff, absmax, diff, i, j,
  67.        length, max, max_diff, new_hi, new_low, width;
  68.  
  69.    struct tiff_header_struct image_header;
  70.  
  71.    create_file_if_needed(in_name, out_name, out_image);
  72.  
  73.    read_tiff_header(in_name, &image_header);
  74.  
  75.    new_hi  = 250;
  76.    new_low = 16;
  77.    if(image_header.bits_per_pixel == 4){
  78.        new_hi  = 10;
  79.        new_low = 3;
  80.    }
  81.  
  82.    max = 255;
  83.    if(image_header.bits_per_pixel == 4)
  84.       max = 16;
  85.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  86.  
  87.    for(i=0; i<ROWS; i++)
  88.       if( (i%10) == 0) printf("%3d", i);
  89.       for(j=0; j<COLS; j++)
  90.          out_image[i][j] = 0;
  91.  
  92.    for(i=1; i<ROWS-1; i++){
  93.       for(j=1; j<COLS-1; j++){
  94.  
  95.           max_diff = 0;
  96.           for(a=-1; a<=1; a++){
  97.              for(b=-1; b<=1; b++){
  98.  
  99.                 diff = the_image[i][j] - 
  100.                         the_image[i+a][j+b];
  101.                 absdiff = abs(diff);
  102.                 if(absdiff > max_diff) 
  103.                    max_diff = absdiff;
  104.  
  105.              }  /* ends loop over b */
  106.           }  /* ends loop over a */
  107.  
  108.           out_image[i][j] = max_diff;
  109.       }  /* ends loop over j */
  110.    }  /* ends loop over i */
  111.  
  112.  
  113.      /* if desired, threshold the output image */
  114.    if(threshold == 1){
  115.        for(i=0; i<ROWS; i++){
  116.           for(j=0; j<COLS; j++){
  117.              if(out_image[i][j] > high){
  118.                   out_image[i][j] = new_hi;
  119.              }
  120.              else{
  121.                   out_image[i][j] = new_low;
  122.              }
  123.           }
  124.        }
  125.    }  /* ends if threshold == 1 */
  126.  
  127.    fix_edges(out_image, 1);
  128.  
  129.    write_array_into_tiff_image(out_name, out_image,
  130.                                il, ie, ll, le);
  131.  
  132.  
  133. } /* ends homogeneity */
  134.  
  135.  
  136.  
  137.  
  138.    /**************************************************
  139.    *
  140.    *   difference_edge(...
  141.    *
  142.    *   This function performs edge detection by looking
  143.    *   at the differences in the pixels that surround
  144.    *   the center point of a 3x3 area.  It replaces the
  145.    *   center point with the absolute value of the
  146.    *   max difference of:
  147.    *      upper left - lower right
  148.    *      upper right - lower left
  149.    *      left - right
  150.    *      top - bottom
  151.    *
  152.    ***************************************************/
  153.  
  154. difference_edge(in_name, out_name, the_image, out_image,
  155.                 il, ie, ll, le, threshold, high)
  156.    char   in_name[], out_name[];
  157.    int    high, il, ie, ll, le, threshold;
  158.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  159. {
  160.    int a, b, absdiff, absmax, diff, i, j,
  161.        length, max, max_diff, new_hi, new_low, width;
  162.  
  163.    struct tiff_header_struct image_header;
  164.  
  165.  
  166.    create_file_if_needed(in_name, out_name, out_image);
  167.  
  168.    read_tiff_header(in_name, &image_header);
  169.  
  170.    new_hi  = 250;
  171.    new_low = 16;
  172.    if(image_header.bits_per_pixel == 4){
  173.        new_hi  = 10;
  174.        new_low = 3;
  175.    }
  176.  
  177.    max = 255;
  178.    if(image_header.bits_per_pixel == 4)
  179.       max = 16;
  180.  
  181.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  182.  
  183.    for(i=0; i<ROWS; i++)
  184.       for(j=0; j<COLS; j++)
  185.          out_image[i][j] = 0;
  186.  
  187.    for(i=1; i<ROWS-1; i++){
  188.       if( (i%10) == 0) printf("%3d", i);
  189.       for(j=1; j<COLS-1; j++){
  190.  
  191.           max_diff = 0;
  192.           absdiff = abs(the_image[i-1][j-1] -
  193.                          the_image[i+1][j+1]);
  194.           if(absdiff > max_diff) max_diff = absdiff;
  195.  
  196.           absdiff = abs(the_image[i-1][j+1] -
  197.                          the_image[i+1][j-1]);
  198.           if(absdiff > max_diff) max_diff = absdiff;
  199.  
  200.           absdiff = abs(the_image[i][j-1] -
  201.                          the_image[i][j+1]);
  202.           if(absdiff > max_diff) max_diff = absdiff;
  203.  
  204.           absdiff = abs(the_image[i-1][j] -
  205.                          the_image[i+1][j]);
  206.           if(absdiff > max_diff) max_diff = absdiff;
  207.  
  208.  
  209.           out_image[i][j] = max_diff;
  210.  
  211.       }  /* ends loop over j */
  212.    }  /* ends loop over i */
  213.  
  214.  
  215.  
  216.      /* if desired, threshold the output image */
  217.    if(threshold == 1){
  218.        for(i=0; i<ROWS; i++){
  219.           for(j=0; j<COLS; j++){
  220.              if(out_image[i][j] > high){
  221.                   out_image[i][j] = new_hi;
  222.              }
  223.              else{
  224.                   out_image[i][j] = new_low;
  225.              }
  226.           }
  227.        }
  228.    }  /* ends if threshold == 1 */
  229.  
  230.  
  231.  
  232.    fix_edges(out_image, 1);
  233.    write_array_into_tiff_image(out_name, out_image,
  234.                                il, ie, ll, le);
  235.  
  236.  
  237. } /* ends difference_edge */
  238.  
  239.  
  240.  
  241.  
  242.  
  243.    /**************************************************
  244.    *
  245.    *   contrast_edge(...
  246.    *
  247.    *   The edge detector uses the basic quick edge
  248.    *   detector mask and then divides the result
  249.    *   by a contrast smooth mask.  This implements
  250.    *   Johnson's contrast based edge detector.
  251.    *
  252.    ***************************************************/
  253.  
  254. contrast_edge(in_name, out_name, the_image, out_image,
  255.                 il, ie, ll, le, threshold, high)
  256.    char   in_name[], out_name[];
  257.    int    high, il, ie, ll, le, threshold;
  258.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  259. {
  260.    int ad, d;
  261.    int a, b, absdiff, absmax, diff, i, j,
  262.        length, max, new_hi, new_low, 
  263.        sum_d, sum_n, width;
  264.  
  265.    struct tiff_header_struct image_header;
  266.  
  267.  
  268.    create_file_if_needed(in_name, out_name, out_image);
  269.  
  270.    read_tiff_header(in_name, &image_header);
  271.  
  272.    new_hi  = 250;
  273.    new_low = 16;
  274.    if(image_header.bits_per_pixel == 4){
  275.        new_hi  = 10;
  276.        new_low = 3;
  277.    }
  278.  
  279.    max = 255;
  280.    if(image_header.bits_per_pixel == 4)
  281.       max = 16;
  282.  
  283.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  284.  
  285.    for(i=0; i<ROWS; i++)
  286.       for(j=0; j<COLS; j++)
  287.          out_image[i][j] = 0;
  288.  
  289.    for(i=1; i<ROWS-1; i++){
  290.       if( (i%10) == 0) printf("%3d", i);
  291.       for(j=1; j<COLS-1; j++){
  292.  
  293.          sum_n = 0;
  294.          sum_d = 0;
  295.  
  296.          for(a=-1; a<2; a++){
  297.             for(b=-1; b<2; b++){
  298.                sum_n = sum_n + the_image[i+a][j+b] *
  299.                        e_mask[a+1][b+1];
  300.                sum_d = sum_d + the_image[i+a][j+b] *
  301.                        contrast[a+1][b+1];
  302.             }
  303.          }
  304.  
  305.          d = sum_d / 9;
  306.          if(d == 0)
  307.             d = 1;
  308.  
  309.          out_image[i][j] = sum_n/d;
  310.  
  311.          if(out_image[i][j] > max) 
  312.             out_image[i][j] = max;
  313.          if(out_image[i][j] < 0) 
  314.             out_image[i][j] = 0;
  315.  
  316.  
  317.       }  /* ends loop over j */
  318.    }  /* ends loop over i */
  319.  
  320.  
  321.  
  322.      /* if desired, threshold the output image */
  323.    if(threshold == 1){
  324.        for(i=0; i<ROWS; i++){
  325.           for(j=0; j<COLS; j++){
  326.              if(out_image[i][j] > high){
  327.                   out_image[i][j] = new_hi;
  328.              }
  329.              else{
  330.                   out_image[i][j] = new_low;
  331.              }
  332.           }
  333.        }
  334.    }  /* ends if threshold == 1 */
  335.  
  336.  
  337.    fix_edges(out_image, 1);
  338.    write_array_into_tiff_image(out_name, out_image,
  339.                                il, ie, ll, le);
  340.  
  341. } /* ends contrast_edge */
  342.  
  343.  
  344.  
  345.  
  346.  
  347.      /*******************************************
  348.      *
  349.      *   range(..
  350.      *
  351.      *   This edge detector performs the
  352.      *   range operation.
  353.      *   It replaces the pixel at the center of a
  354.      *   3x3, 5x5, etc. area with the max - min
  355.      *   for that area.
  356.      *
  357.      *******************************************/
  358.  
  359. range(in_name, out_name, the_image, out_image,
  360.       il, ie, ll, le, size, threshold, high)
  361.    char   in_name[], out_name[];
  362.    int    il, ie, ll, le,
  363.           high, threshold, size;
  364.    short  the_image[ROWS][COLS],
  365.           out_image[ROWS][COLS];
  366.  
  367. {
  368.    int    a, b, count, i, j, k,
  369.           new_hi, new_low, length,
  370.           sd2, sd2p1, ss, width;
  371.    short  *elements;
  372.    struct tiff_header_struct image_header;
  373.  
  374.    sd2   = size/2;
  375.    sd2p1 = sd2 + 1;
  376.  
  377.       /**********************************************
  378.       *
  379.       *   Allocate the elements array large enough
  380.       *   to hold size*size shorts.
  381.       *
  382.       **********************************************/
  383.  
  384.    ss       = size*size;
  385.    elements = (short *) malloc(ss * sizeof(short));
  386.  
  387.    create_file_if_needed(in_name, out_name, out_image);
  388.  
  389.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  390.  
  391.    new_hi  = 250;
  392.    new_low = 16;
  393.    if(image_header.bits_per_pixel == 4){
  394.        new_hi  = 10;
  395.        new_low = 3;
  396.    }
  397.  
  398.       /***************************
  399.       *
  400.       *   Loop over image array
  401.       *
  402.       ****************************/
  403.  
  404.    printf("\n");
  405.    for(i=sd2; i<ROWS-sd2; i++){
  406.       if( (i%10) == 0) printf("%d ", i);
  407.       for(j=sd2; j<COLS-sd2; j++){
  408.          count = 0;
  409.          for(a=-sd2; a<sd2p1; a++){
  410.             for(b=-sd2; b<sd2p1; b++){
  411.                elements[count] = the_image[i+a][j+b];
  412.                count++;
  413.             }
  414.          }
  415.          sort_elements(elements, &ss);
  416.          out_image[i][j] = elements[ss-1]-elements[0];
  417.       }  /* ends loop over j */
  418.    }  /* ends loop over i */
  419.  
  420.      /* if desired, threshold the output image */
  421.    if(threshold == 1){
  422.        for(i=0; i<ROWS; i++){
  423.           for(j=0; j<COLS; j++){
  424.              if(out_image[i][j] > high){
  425.                   out_image[i][j] = new_hi;
  426.              }
  427.              else{
  428.                   out_image[i][j] = new_low;
  429.              }
  430.           }
  431.        }
  432.    }  /* ends if threshold == 1 */
  433.  
  434.    fix_edges(out_image, sd2);
  435.  
  436.    write_array_into_tiff_image(out_name, out_image,
  437.                                il, ie, ll, le);
  438.  
  439.    free(elements);
  440.  
  441. }  /* ends range */
  442.  
  443.  
  444.  
  445.  
  446.  
  447.    /**************************************************
  448.    *
  449.    *   variance(...
  450.    *
  451.    *   This function replaces the pixel in the center
  452.    *   of a 3x3 area with the square root of the sum 
  453.    *   of squares of the differences between the 
  454.    *   center pixel and its eight neighbors.
  455.    *
  456.    ***************************************************/
  457.  
  458. variance(in_name, out_name, the_image, out_image,
  459.          il, ie, ll, le, threshold, high)
  460.    char   in_name[], out_name[];
  461.    int    il, ie, ll, le, high, threshold;
  462.    short  the_image[ROWS][COLS],
  463.           out_image[ROWS][COLS];
  464. {
  465.    int      a, b, i, j, length,
  466.             max, new_hi, new_low, width;
  467.    long     diff;
  468.    unsigned long sum, tmp;
  469.  
  470.    struct tiff_header_struct image_header;
  471.  
  472.  
  473.    create_file_if_needed(in_name, out_name, out_image);
  474.  
  475.    read_tiff_header(in_name, &image_header);
  476.  
  477.    new_hi  = 250;
  478.    new_low = 16;
  479.    if(image_header.bits_per_pixel == 4){
  480.        new_hi  = 10;
  481.        new_low = 3;
  482.    }
  483.  
  484.    max = 255;
  485.    if(image_header.bits_per_pixel == 4)
  486.       max = 16;
  487.  
  488.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  489.  
  490.    for(i=1; i<ROWS-1; i++){
  491.       if( (i%10) == 0) printf("%3d", i);
  492.       for(j=1; j<COLS-1; j++){
  493.          sum = 0;
  494.          for(a=-1; a<=1; a++){
  495.              for(b=-1; b<=1; b++){
  496.                 if( a!=0  &&  b!=0){
  497.                  diff = 0;
  498.                  diff = the_image[i][j] -
  499.                         the_image[i+a][j+b];
  500.                  tmp = diff*diff;
  501.                  sum = sum + tmp;
  502.                 }
  503.              }
  504.          }
  505.          if(sum < 0)
  506.             printf("\nWHAT? sum < 0, %ld ,diff=%d ", sum, diff);
  507.          sum = sqrt(sum);
  508.          if(sum > max) sum = max;
  509.          out_image[i][j] = sum;
  510.       }  /* ends loop over j */
  511.    }  /* ends loop over i */
  512.  
  513.       /* if desired, threshold the output image */
  514.    if(threshold == 1){
  515.        for(i=0; i<ROWS; i++){
  516.           for(j=0; j<COLS; j++){
  517.              if(out_image[i][j] > high){
  518.                   out_image[i][j] = new_hi;
  519.              }
  520.              else{
  521.                   out_image[i][j] = new_low;
  522.              }
  523.           }
  524.        }
  525.    }  /* ends if threshold == 1 */
  526.  
  527.  
  528.    fix_edges(out_image, 1);
  529.    write_array_into_tiff_image(out_name, out_image,
  530.                                il, ie, ll, le);
  531.  
  532. } /* ends variance */
  533.